// converter_aes_rsa.js
const ffmpeg = require("fluent-ffmpeg")
const fs = require("fs")
const path = require("path")
const crypto = require("crypto")
const {
  generateRSAKeyPair,
  encryptAESKey,
  generateAESKey,
  createKeyInfoFile
} = require("./converter_aes_rsa_utils")

// 输入输出路径设置 /public/drm
const input = path.resolve(__dirname, "input1.mp4")
const output = path.resolve(__dirname, "../public/drm")

function convertToEncryptedHLS(inputPath, outputDir) {
  return new Promise((resolve, reject) => {
    // 检查输入文件是否存在
    if (!fs.existsSync(inputPath)) {
      reject(new Error(`输入文件不存在: ${inputPath}`))
      console.log(`输入文件不存在: ${inputPath}`)
      return
    }

    // 确保输出目录存在
    if (!fs.existsSync(outputDir)) {
      fs.mkdirSync(outputDir, { recursive: true })
      console.log("输出目录创建成功")
    }

    // 1. 生成RSA密钥对
    const { publicKey, privateKey } = generateRSAKeyPair()
    // const privateKeyPath = path.join(__dirname, "../keys", "rsa_private.pem")

    // 2. 生成AES密钥
    const aesKey = generateAESKey()
    console.log("AES密钥已生成")

    // 3. 使用RSA公钥加密AES密钥
    const encryptedAESKey = encryptAESKey(aesKey, publicKey)

    // 保存加密后的AES密钥
    const keyName = "encryption.key"
    const encryptedKeyPath = path.join(outputDir, keyName)
    fs.writeFileSync(encryptedKeyPath, encryptedAESKey)
    console.log(`AES密钥已用RSA加密并保存: ${encryptedKeyPath}`)

    // 保存原始AES密钥(仅用于测试，实际使用时应删除)
    fs.writeFileSync(path.join(outputDir, "original.key"), aesKey)

    // 为FFmpeg创建临时AES密钥文件(转换完成后将删除)
    const tempKeyPath = path.join(outputDir, "temp.key")
    fs.writeFileSync(tempKeyPath, aesKey)

    // 设置密钥服务器URL - 指向DRM服务器
    const keyServerUrl = "http://localhost:3000/drm/key"

    // 创建密钥信息文件
    const keyInfoPath = path.join(outputDir, "enc_key_info.keyinfo")
    const iv = crypto.randomBytes(16)
    createKeyInfoFile(keyInfoPath, keyServerUrl, tempKeyPath, iv)
    console.log(`密钥信息文件已创建: ${keyInfoPath}`)

    console.log(`开始加密转换: ${inputPath} -> ${outputDir}`)

    ffmpeg(inputPath)
      .videoCodec("libx264")
      .audioCodec("aac")
      .outputOptions([
        "-hls_time 10", // 分段时间
        "-hls_list_size 0", // 包含所有分段
        `-hls_segment_filename ${outputDir}/segment_%03d.ts`, // 分段名
        `-hls_key_info_file ${keyInfoPath}`, // 密钥信息文件
        "-hls_playlist_type vod", // 点播类型
        "-f hls" // 转换格式
      ])
      .output(`${outputDir}/index.m3u8`)
      .on("start", commandLine => {
        console.log("FFmpeg命令:", commandLine)
      })
      .on("progress", progress => {
        if (progress.percent) {
          console.log(`转换进度: ${Math.round(progress.percent)}%`)
        }
      })
      .on("stderr", stderrLine => {
        // console.log("FFmpeg输出:", stderrLine);
      })
      .on("end", () => {
        console.log("加密转换完成!")

        // 删除临时AES密钥文件
        try {
          fs.unlinkSync(tempKeyPath)
          console.log("临时密钥文件已删除")
        } catch (err) {
          console.error("删除临时密钥文件失败:", err)
        }
        resolve(`${outputDir}/index.m3u8`)
      })
      .on("error", (err, stdout, stderr) => {
        console.error("加密转换失败:", err.message)
        reject(err)
      })
      .run()
  })
}

/**
 * 调用转换
 */
convertToEncryptedHLS(input, output)
  .then(res => {
    console.log("转换完成：", res)
  })
  .catch(err => {
    console.error(err.message)
  })
